package smallfrench.moteur.biblio;

import smallfrench.moteur.biblio.err.ErreurParametres;
import smallfrench.moteur.interp.RObjet;

public class RClasseDecimal extends RClasse {

	public static final RClasseDecimal CLASSE = new RClasseDecimal();

	private RClasseDecimal() {

		super(new RClasse[] {RClasse.CLASSE});

		ajouterChampStatique("E", RDecimal.E);
		ajouterChampStatique("PI", RDecimal.PI);
		ajouterChampStatique("ZERO", RDecimal.ZERO);
		ajouterChampStatique("UN", RDecimal.UN);

		champs.put("abs", fnAbs);
		champs.put("enChaine", fnEnChaine);
	};

	@Override
	public RDecimal appeler(RObjet moi, RObjet[] args) {

		if (args.length == 0) {

			return RDecimal.ZERO;

		} else if (args.length == 1) {

			RObjet arg = args[0];

			if (arg instanceof REntier) {
				return new RDecimal(((REntier)arg).valeur);

			} else if (arg instanceof RFlottant) {
				return new RDecimal(((RFlottant)arg).valeur);

			} else if (arg instanceof RChaine) {
				return RDecimal.creer(((RChaine)arg).valeur);

			} else if (arg instanceof RDecimal) {
				return (RDecimal) arg;
			}
		}
		throw ErreurParametres.nouvelleException();
	}



	@Override
	public RChaine enChaine() {
		return new RChaine("Decimal");
	}


	private static abstract class Fonction extends RFonction {

		public abstract RObjet appeler2(RDecimal moi, RObjet[] params);

		@Override
		public final RObjet appeler(RObjet moi, RObjet[] params) {
			if (moi instanceof RDecimal)
				return appeler2((RDecimal)moi, params);
			return null;
		}
	}

	/**
	 * Valeur absolue
	 */
	private final Fonction fnAbs = new Fonction() {
		@Override
		public RObjet appeler2(RDecimal moi, RObjet[] params) {
			return new RDecimal(moi.valeur.abs());
		}
	};
	private final Fonction fnEnChaine = new Fonction() {
		@Override
		public RObjet appeler2(RDecimal moi, RObjet[] params) {
			return moi.enChaine();
		}
	};
}
